# 孙宇 去了一家 xx科技有限公司,程序员.
# 主管让孙宇完成一个支付功能.

# 版本1:
# class QQpay:
#
#     def pay(self,money):  # 鸭子类型
#         print(f'使用qq支付了{money}')
#
#
# class Alipay:
#
#     def pay(self,money):
#         print(f'使用阿里支付了{money}')
#
#
# obj1 = QQpay()
# obj1.pay(100)  # 支付接口
#
# obj2 = Alipay()
# obj2.pay(200)

# 版本2: 要做到统一接口

# class QQpay:
#
#     def pay(self,money):  # 鸭子类型
#         print(f'使用qq支付了{money}')
#
#
# class Alipay:
#
#     def pay(self,money):
#         print(f'使用阿里支付了{money}')
#
#
# def pay(obj,money):  # 归一化设计 :统一接口
#     obj.pay(money)
#
#
# obj1 = QQpay()
# obj2 = Alipay()
#
# pay(obj1,100)
# pay(obj2,200)


# 版本3: 招了程序员,完善支付功能.



# class QQpay:
#
#     def pay(self,money):  # 鸭子类型
#         print(f'使用qq支付了{money}')
#
#
# class Alipay:
#
#     def pay(self,money):
#         print(f'使用阿里支付了{money}')
#
#
# class Wechat:
#     def fuqian(self,money):
#         print(f'使用微信支付了{money}')
#
#
# def pay(obj,money):  # 归一化设计 :统一接口
#     obj.pay(money)
#
#
# obj1 = QQpay()
# obj2 = Alipay()
#
# pay(obj1,100)
# pay(obj2,200)
#
# obj3 = Wechat()
# obj3.fuqian(300)


# 版本4: 制定约束.约定俗称,没有做到完全强制.

# class Payment:
#
#     def pay(self,money):
#         pass
#
#
# class QQpay(Payment):
#
#     def pay(self,money):  # 鸭子类型
#         print(f'使用qq支付了{money}')
#
#
# class Alipay(Payment):
#
#     def pay(self,money):
#         print(f'使用阿里支付了{money}')
#
#
# class Wechat(Payment):
#     def fuqian(self,money):
#         print(f'使用微信支付了{money}')
#
#
# def pay(obj,money):  # 归一化设计 :统一接口
#     obj.pay(money)
#
#
# obj1 = QQpay()
# obj2 = Alipay()
#
# pay(obj1,100)
# pay(obj2,200)
#
# obj3 = Wechat()
# obj3.fuqian(300)


# 版本五 :做到强制约束.
# 方法1: python语言惯于使用的一种约束方式,在父类主动抛出错误.
# 方法2: 借鉴于Java语言,定义抽象类的概念,做到真正的强制约束.


# 方法一:

# 前提,你的项目已经上线了,之前完成的QQpay,Alipay 以及 pay函数这个接口都成型.
# 如果此时新添加一个微信支付,其他的py文件引用支付功能时还是直接引用pay.
# class Payment:
#
#     def pay(self,money):
#         raise Exception('你的子类需要定义pay方法')
#
#
# class QQpay(Payment):
#
#     def pay(self,money):  # 鸭子类型
#         print(f'使用qq支付了{money}')
#
#
# class Alipay(Payment):
#
#     def pay(self,money):
#         print(f'使用阿里支付了{money}')
#
#
# class Wechat(Payment):
#
#     def fuqian(self,money):
#         print(f'使用微信支付了{money}')
#
#
# def pay(obj,money):  # 归一化设计 :统一接口
#     obj.pay(money)

#
# obj1 = QQpay()
# obj2 = Alipay()
#
# pay(obj1,100)
# pay(obj2,200)
#
# obj3 = Wechat()
# obj3.fuqian(300)

# raise Exception('主动报错!')
# print(111)

# 方法二:
from abc import ABCMeta,abstractmethod

# 抽象类,接口类: 强制指定规则(规范).
class Payment(metaclass=ABCMeta):  #指定元类

    @abstractmethod
    def pay(self,money):
        pass


class QQpay(Payment):

    def pay(self,money):  # 鸭子类型
        print(f'使用qq支付了{money}')


class Alipay(Payment):

    def pay(self,money):
        print(f'使用阿里支付了{money}')


class Wechat(Payment):

    def fuqian(self,money):
        print(f'使用微信支付了{money}')

    # def pay(self,money):  # 强制定义
    #     pass


def pay(obj,money):  # 归一化设计 :统一接口
    obj.pay(money)

obj3 = Wechat()


